package com.example.landlord.demo.utils.system;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.JsonNodeFactory;
import com.fasterxml.jackson.databind.node.ObjectNode;
import org.java_websocket.WebSocket;

import java.util.ArrayList;
import java.util.UUID;

public class Game extends Thread{
    GameType gameType = GameType.NOGAME;
    volatile ArrayList<Player> players =new ArrayList<>();  //玩家池
    GameStatus gameStatus=GameStatus.WAITING;       //默认为等待玩家进入状态
    String id;                                      //游戏房间编号
    String name;                                    //游戏房间名称
    Player createdPlayer;                           //游戏房间创建者
    int num;                                        //该游戏最少必须有几个玩家
    MyWebSocketServer myWebSocketServer;

    public Game(MyWebSocketServer myWebSocketServer){
        //生成房间ID
        id= UUID.randomUUID().toString();
        this.myWebSocketServer=myWebSocketServer;
    }

    //初始化游戏函数
    public void runGame(){
        //等待重写
    }

    //游戏整体函数
    public boolean gameDoing(WebSocketMessage webSocketMessage){
        return false;
    }

    public void sendGameStatus(){
        ObjectMapper objectMapper = new ObjectMapper();
        ObjectNode result = objectMapper.createObjectNode();
        boolean start= gameStatus==GameStatus.STARTED;
        result.put("order",6);
        result.put("result",start);

        if(start){
            int type=0;
            switch (gameType){
                case LANDLORD:
                    type=1;
                    break;
            }
            result.put("game",type);
        }
        try{
            for(Player p : players){
                p.user.webSocket.send(objectMapper.writeValueAsString(result));
            }
        }catch (JsonProcessingException e){}

    }

    //玩家在游戏开始后中途退出游戏事件
    public void playerExit(Player p){
        p.online=false;
    }

    //玩家游戏途中重新连接后事件
    public void playerReloading(User user){
        System.out.println("玩家重连接");
        for(Player p : players){
            if(p.user.id.equals(user.id)){
                p.user=user;
                p.online=true;
                break;
            }
        }
    }

    //加入玩家
    public synchronized boolean addPlayer(Player p){
        //检查该玩家是否正在参加其他游戏
        if(p.user.gameType!=GameType.NOGAME){
            System.out.println(p.user.name+"有其他游戏正在进行,不能参加该局游戏!");
            return false;
        }
        //玩家是否已满
        if(players.size()<3){
            p.user.gameType=gameType;
            p.user.game=this;
            players.add(p);
            System.out.println(p.user.name+"加入了游戏");
            if(players.size()==1){
                //如果是第一个加入的玩家，那它自动是房主
                createdPlayer=p;
            }
            p.online=true;
            //给所有玩家广播该玩家加入消息
            sendPlayersMessage();
            return true;
        }else{
            return false;
        }
    }

    public synchronized boolean removePlayer(Player p){
        for(Player player : players){
            if(player.user.webSocket==p.user.webSocket){
                players.remove(player);
                player.user.gameType=GameType.NOGAME;
                player.user.game=null;
                sendPlayersMessage();
                if(players.size()!=0){
                    //任命下一个玩家为游戏创建者
                    createdPlayer=players.get(0);
                }else {
                    //删除该空房间
                    delGame();
                }
                return true;
            }
        }
        sendPlayersMessage();
        return false;
    }

    //删除房间，等待重写
    public void delGame(){}

    //通知前端更新玩家列表
    public void sendPlayersMessage(){
        ObjectMapper objectMapper = new ObjectMapper();
        ObjectNode objectNode = objectMapper.createObjectNode();
        objectNode.put("order",1);
        ArrayNode playerList = JsonNodeFactory.instance.arrayNode();
        for(Player player:players){
            ObjectNode p = objectMapper.createObjectNode();
            p.put("name",player.user.name);
            p.put("id", player.user.id);
            p.put("picture",player.user.picture);
            p.put("ready", player.ready);
            playerList.add(p);
        }
        objectNode.put("created", createdPlayer.user.id);
        objectNode.put("players",playerList);
        try{
            String json=objectMapper.writeValueAsString(objectNode);
            for(Player p:players){
                p.user.webSocket.send(json);
            }
        }catch (JsonProcessingException e){
            return;
        }

    }

    public GameStatus getGameStatus() {
        return gameStatus;
    }

    public Player getPlayerBySocket(WebSocket webSocket){
        for(Player player:players){
            if(player.user.webSocket==webSocket){
                return player;
            }
        }
        return null;
    }

    //已经准备好的玩家数量
    public int countReadyPlayer(){
        int count=0;
        for(Player player:players){
            if(player.ready){
                count++;
            }
        }
        return count;
    }

    //开启游戏
    public boolean startGame(WebSocket webSocket){
        //检查玩家数目是否小于最少玩家数且所有玩家处于准备状态
        Player p = getPlayerBySocket(webSocket);
        //判断是否为房主
        System.out.println("is:"+(p==createdPlayer));
        if(p==createdPlayer){
            if(players.size()<num-1 || countReadyPlayer()!=num-1){
                System.out.println(p.user.name+"启动游戏失败，因为准备玩家数量不足");
                return false;
            }
            //直接开启游戏
            runGame();
        }else{
            //只是准备
            p.ready=true;
            System.out.println(p.user.name+"已准备");
            sendPlayersMessage();
        }
        return true;
    }
}
